package com.selen.utils;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import io.minio.MinioClient;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Selen
 */
@Slf4j
public class MinioUtil {

    /** Minio客户端 */
    private static MinioClient minioClient;
    private final static String END_POINT = "http://192.168.197.77:9001";
    private final static String ACCESS_KEY="Ed7NVvDlR7JeFXzz6eNx";
    private final static String SECRET_KEY="AC29LwPIFSWp7rqa926zpQcxJKWbpS8yo4OifrjR";

    static {
        try {
            // 创建MinIO客户端
            minioClient = new MinioClient(END_POINT, ACCESS_KEY, SECRET_KEY);
        } catch (Exception e) {
            log.error("MinioClient实例化失败: {}", e.getMessage());
        }
    }

    /**
     * 将文件上传到MinIO对象存储服务中
     *
     * @param file       文件对象
     * @param filename   文件名称
     * @param dir        文件存储目录
     * @param bucketName MinIO桶名
     */
    @SneakyThrows
    public static void upload(MultipartFile file, String filename, String dir, String bucketName) {

        // 校验数据桶是否存在
        checkBucket(bucketName);

        // 校验上传目录
        checkDir(dir);

        // 使用putObject上传文件到指定Bucket
        minioClient.putObject(bucketName, dir + "/" + filename,
                file.getInputStream(),
                file.getContentType());
    }

    /**
     * 根据文件对象获取随机文件名称
     *
     * @param file 文件对象
     * @return 随机文件名称，格式为 "UUID后10位 + 当前时间戳 + 原始文件后缀"
     */
    public static String randomFilename(MultipartFile file) {

        // 校验文件对象
        checkMultipartFile(file);

        // 获取原始文件名
        String filename = file.getOriginalFilename();

        // 校验原始文件名
        checkFileName(filename);

        // 生成随机文件名并返回
        return UUID.randomUUID().toString().substring(26) + "-"
                + System.currentTimeMillis()
                + filename.substring(filename.lastIndexOf("."));
    }

    /**
     * 删除指定文件
     * @param fileName 文件名
     * @param dir 文件夹
     * @param bucketName 桶名
     */
    @SneakyThrows
    public static void delete(String fileName, String dir, String bucketName){
        checkFileName(fileName);
        checkDir(dir);
        minioClient.removeObject(bucketName, dir + "/" + fileName);
    }

    /**
     * 检查文件对象是否为 null
     * @param multipartFile
     */
    private static void checkMultipartFile(MultipartFile multipartFile){
        if (ObjectUtil.isNull(multipartFile)){
            throw new RuntimeException("文件对象为空");
        }
    }

    /**
     * 检查文件名是否为 null 或 ”“
     * @param filename
     */
    private static void checkFileName(String filename){
        if (StrUtil.isBlank(filename)) {
            throw new RuntimeException(" 文件名为空");
        }
    }

    /**
     * 检查文件目录是否为 null 或 ”“
     * @param dir
     */
    private static void checkDir(String dir){
        if (StrUtil.isBlank(dir)) {
            throw new RuntimeException("文件上传目录为空");
        }
    }

    /**
     * 检查桶名是否为 null 或 ”“，桶是否存在
     * @param bucketName
     */
    @SneakyThrows
    private static void checkBucket(String bucketName){
        if (StrUtil.isEmpty(bucketName)){
            throw new RuntimeException("桶名不存在");
        }
        if (!minioClient.bucketExists(bucketName)) {
            throw new RuntimeException("MinIO桶不存在");
        }
    }

}
